#include "bsp_adc.h"

uint32_t    laser_fre[2] = {0, 0};

/*!
    \brief      configure the different system clocks
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void rcu_config(void) {
	/* enable GPIOA clock */
	rcu_periph_clock_enable(RCU_GPIOA);
	/* enable DMA clock */
	rcu_periph_clock_enable(RCU_DMA0);
	/* enable TIMER0 clock */
	rcu_periph_clock_enable(ADC_PWM_TMER_RCU);
	/* enable ADC2 clock */
	rcu_periph_clock_enable(ADC_RCU);
	/* config ADC clock */
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV6);
}

//Timer4配置初始化
void App_Timer4Cfg(void) {
	/* TIMER0 配置：产生不同占空比的 PWM 信号：
	  TIMER0CLK = SystemCoreClock / 120 = 1MHz */
	timer_parameter_struct timer_initpara;
	timer_oc_parameter_struct timer_ocintpara;

	rcu_periph_clock_enable(ADC_PWM_TMER_RCU);  //开启定时器时钟
	timer_deinit(ADC_PWM_TMER);     //取消定时器
	/* TIMERX 配置 */
	timer_initpara.prescaler         = 11999;
	timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;        //向上计数
	timer_initpara.period            = 100 - 1;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_initpara.repetitioncounter = 0;
	timer_init(ADC_PWM_TMER, &timer_initpara);

	/* CHX configuration in PWM mode0 */
	timer_channel_output_struct_para_init(&timer_ocintpara);
	timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
	timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
	timer_channel_output_config(ADC_PWM_TMER, ADC_PWM_CH, &timer_ocintpara);

	timer_channel_output_pulse_value_config(ADC_PWM_TMER, ADC_PWM_CH, 50);
	timer_channel_output_mode_config(ADC_PWM_TMER, ADC_PWM_CH, TIMER_OC_MODE_PWM0);
	timer_channel_output_shadow_config(ADC_PWM_TMER, ADC_PWM_CH, TIMER_OC_SHADOW_DISABLE);

	/* auto-reload preload enable */
	timer_auto_reload_shadow_enable(ADC_PWM_TMER);
}


/*!
    \brief      直接存储器存取配置功能
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dma_config(void) {
	dma_parameter_struct dma_init_struct;

	/* 初始化DMA channel0 */
	dma_deinit(DMA0, DMA_CH0);
	dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;            /*!< 从外设读取并写入内存 */
	dma_init_struct.memory_addr  = (uint32_t)laser_fre;                 //目标地址
	dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;          /*!< 内存的下一个地址是递增地址模式 */
	dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;              /*!< 传输数据的内存大小为16位 */
	dma_init_struct.number       = LASWER_FRE_NUME * ADC_CHANNEL_NUMER;                     //传输的个数
	dma_init_struct.periph_addr  = (uint32_t)(&ADC_RDATA(ADC_NUM_CH));      //源地址
	dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;         /*!< 外设的下一个地址为固定地址模式   */
	dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;          /*!< 外设传输数据大小为16位 */
	dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;             /*!< 超高的优先级 */
	dma_init(DMA0, DMA_CH0, &dma_init_struct);
	/* 配置DMA模式 */
	dma_circulation_enable(DMA0, DMA_CH0);
	//中断配置
	nvic_irq_enable(DMA0_Channel0_IRQn, 0, 1);
	dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF);
	/* 支持DMA channel0*/
	dma_channel_enable(DMA0, DMA_CH0);
}

//-------------------------------------------------------------------------------
//函数名：App_AdcInit
//输   入：void
//输   出：void
//功   能：ADC 模块初始化,ADCCLK =4MHz，4MHz/28 = 142.8kHz
//-----------------------------------------------------------------------------
void App_AdcInit(void) {
	adc_deinit(ADC_NUM_CH);
	/* 开启ADC扫描模式功能 */
	adc_special_function_config(ADC_NUM_CH, ADC_SCAN_MODE, ENABLE);
	/* ADC通道数量配置 */
	adc_channel_length_config(ADC_NUM_CH, ADC_REGULAR_CHANNEL, 2);
	/* ADC常规通道配置 */
	adc_regular_channel_config(ADC_NUM_CH, 0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
	adc_regular_channel_config(ADC_NUM_CH, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
	//  adc_regular_channel_config(ADC_NUM_CH,2, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
	/* ADC外部触发启用 */
	adc_external_trigger_config(ADC_NUM_CH, ADC_REGULAR_CHANNEL, ENABLE);
	/* ADC外部触发源配置 */
	adc_external_trigger_source_config(ADC_NUM_CH, ADC_REGULAR_CHANNEL, ADC_EXTTRIG_CH);
	/* ADC转换速率配置 */
	adc_resolution_config(ADC_NUM_CH, ADC_RESOLUTION_12B);
	/* ADC数据对齐配置 */
	adc_data_alignment_config(ADC_NUM_CH, ADC_DATAALIGN_RIGHT);
	/* 启用ADC接口 */
	adc_enable(ADC_NUM_CH);
	/* ADC校准和复位校准 */
	adc_calibration_enable(ADC_NUM_CH);
	/* ADC DMA功能使能 */
	adc_dma_mode_enable(ADC_NUM_CH);
}

/*
*********************************************************************************************************
*   函 数 名: void App_datacollection_PORT_init(void)
*   功能说明: 数据采集端口配置
*   形    参: 无
*   返 回 值: 无
*********************************************************************************************************
*/
void App_datacollection_PORT_init(void) {
	/*configure PA8(TIMER0 CH0) as alternate function*/
	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_1);
	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_MAX, GPIO_PIN_0);
}

//ADC初始化
void ADC_init(void) {
	rcu_config();
	App_datacollection_PORT_init();//端口初始化
	App_Timer4Cfg();
	dma_config();
	App_AdcInit();//模块初始化
	timer_enable(ADC_PWM_TMER);
}

/**ADC停止采样**/
void ADC_stop(void) {
	timer_channel_output_mode_config(ADC_PWM_TMER, ADC_PWM_CH, TIMER_OC_MODE_HIGH);
}

/**ADC启动采样**/
void ADC_start(void) {
	timer_channel_output_mode_config(ADC_PWM_TMER, ADC_PWM_CH, TIMER_OC_MODE_PWM1);
}

//当传输完成足够的数据后,就关闭定时器,设置标志位,进行处理,可以在中断中处理,
void DMA0_Channel0_IRQHandler(void) {
	//传输完成标志位
	if (dma_interrupt_flag_get(DMA0, DMA_CH0, DMA_INT_FLAG_FTF)) {
		//关闭定时器,停止继续读取数据
		//timer_channel_output_mode_config(ADC_PWM_TMER, ADC_PWM_CH, TIMER_OC_MODE_HIGH);



		//清除全部标志位
		dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_G);
	}

}
